package cn.zf233.springsecurityjwt.config.sms;

import cn.zf233.springsecurityjwt.util.TestVCodePool;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;

/**
 * Created by zf233 on 2021/7/12
 */
@Component("smsAuthenticationProvider")
public class SmsAuthenticationProvider implements AuthenticationProvider {

    @Resource
    private SmsDetailsService smsDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String phone = authentication.getName();
        String code = (String) authentication.getCredentials();
        if (StringUtils.isBlank(phone)) {
            throw new UsernameNotFoundException("手机号不可以为空");
        }
        if (StringUtils.isBlank(code)) {
            throw new BadCredentialsException("验证码不可以为空");
        }
        //验证短信验证码
        /*String key = phoneNo + WebConstant.REDIS_KEY_SUFFIX_FOR_VERIFICATION_CODE;
        boolean hasCode = redisCacheUtil.hasKey(key);
        if (!hasCode) {
            throw new BadCredentialsException("短信验证码已失效请重新获取");
        }
        String smsCode = redisCacheUtil.getString(key);
        //比较前端传入的明文和数据库中加密的密文是否相等
        if (!smsCode.equalsIgnoreCase(code)) {
            throw new BadCredentialsException("验证码错误");
        }
        redisCacheUtil.delete(key);*/

        String vCode = TestVCodePool.get(phone);
        if (StringUtils.isBlank(vCode)) {
            throw new BadCredentialsException("短信验证码已失效请重新获取");
        }
        if (!vCode.equals(code)) {
            throw new BadCredentialsException("验证码错误");
        }

        //获取用户信息
        UserDetails user = smsDetailsService.loadUserByUsername(phone);
        if (ObjectUtils.isEmpty(user)) {
            throw new BadCredentialsException("用户信息加载失败");
        }

        TestVCodePool.remove(phone);

        return new SmsAuthenticationToken(user, null, null);
    }
    

    @Override
    public boolean supports(Class<?> aClass) {
        return SmsAuthenticationToken.class.isAssignableFrom(aClass);
    }
}